package com.heima.wemedia.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.heima.common.constants.BehaviorConstants;
import com.heima.common.redis.CacheService;
import com.heima.model.article.dtos.ArticleInfoDto;
import com.heima.model.channel.dtos.ChannelDto;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.model.wemedia.pojos.WmChannel;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.utils.thread.AppThreadLocalUtil;
import com.heima.wemedia.mapper.WmChannelMapper;
import com.heima.wemedia.service.WmChannelService;
import com.heima.wemedia.service.WmNewsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Transactional
@Slf4j
public class WmChannelServiceImpl extends ServiceImpl<WmChannelMapper, WmChannel> implements WmChannelService {
    @Autowired
    private WmNewsService wmNewsService;
    @Autowired
    private CacheService cacheService;
    /**
     * 查询所有频道
     */
    @Override
    public ResponseResult<List<WmChannel>> findAll() {
        return ResponseResult.okResult(list());
    }

    /**
     * 删除频道
     */
    @Override
    public ResponseResult<String> delChannel(Integer id) {
        // 1. 参数校验
        if (id == null || id <= 0) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        // 2. 获取频道信息
        WmChannel wmChannel = getById(id);
        if (wmChannel == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST, "暂无此频道信息");
        }

        // 3. 判断频道是否有效
        if (wmChannel.getStatus()) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "此频道有效，不可删除");
        }

        // 4. 判断频道是否被引用 -- 是否有文章引用了该频道, 且该文章处于发布状态(9)
        if (isCited(wmChannel)) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "此频道被引用，不可删除");
        }

        // 5. 删除频道
        String isRemove = removeById(id) ? "删除成功" : "删除失败";
        String info = String.format("频道 { %d:%s } %s", id, wmChannel.getName(), isRemove);
        log.info(info);
        return ResponseResult.okResult(info);
    }

    /**
     * 判断频道是否被引用
     * @param wmChannel 频道信息
     */
    private boolean isCited(WmChannel wmChannel) {
        int count = wmNewsService.lambdaQuery()
                .eq(WmNews::getChannelId, wmChannel.getId())
                .eq(WmNews::getStatus, WmNews.Status.PUBLISHED.getCode())
                .count();
        return count > 0;
    }

    /**
     * 频道搜索
     */
    @Override
    public ResponseResult<List<WmChannel>> likeQuery(ChannelDto channelDto) {
        // 1. 参数校验
        if (channelDto == null || StringUtils.isBlank(channelDto.getName())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        channelDto.auditParams(); // 分页参数校验

        // 2. 搜索频道信息
        Page<WmChannel> page = new Page<>(channelDto.getPage(), channelDto.getSize());

        return ResponseResult.okResult(page(page).getRecords());
    }

    /**
     *  修改频道信息
     * @param wmChannel 修改信息
     */
    @Override
    public ResponseResult<String> modifyChannel(WmChannel wmChannel) {
        // 1. 参数校验
        if (wmChannel == null || wmChannel.getId() == null || wmChannel.getId() <= 0 
                || StringUtils.isBlank(wmChannel.getName())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        // 2. 查询频道是否存在
        WmChannel channel = getById(wmChannel.getId());
        if (channel == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_NOT_EXIST);
        }
        
        // 3. 判断频道是否被引用
        if (isCited(channel)) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID, "此频道被引用，不可修改");
        }

        // 4. 修改频道信息
        wmChannel.setCreatedTime(new Date());


        return ResponseResult.okResult(updateById(wmChannel) ? "频道修改成功" : "频道修改失败");
    }

    /**
     * 新增频道
     * @param wmChannel 新增信息
     */
    @Override
    public ResponseResult<String> addChannel(WmChannel wmChannel) {
        // 1. 参数校验
        if (wmChannel == null || StringUtils.isBlank(wmChannel.getName())) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        // 2. 判断频道是否存在
        WmChannel channel = lambdaQuery().eq(WmChannel::getName, wmChannel.getName()).one();
        if (channel != null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.DATA_EXIST, "此频道已存在");
        }

        // 3. 校验频道信息, 若部分值为空, 使用默认值
        auditParams(wmChannel);

        // 4. 新增频道

        return ResponseResult.okResult(save(wmChannel) ? "频道新增成功" : "频道新增失败");
    }

    /**
     * 参数校验
     * @param wmChannel 频道信息
     */
    private void auditParams(WmChannel wmChannel) {
        if (wmChannel.getStatus() == null) {
            wmChannel.setStatus(true); // 默认频道有效/启用
        }
        if (wmChannel.getOrd() == null) {
            wmChannel.setOrd(0); // 默认排序为0
        }
        if (wmChannel.getCreatedTime() == null) {
            wmChannel.setCreatedTime(new Date()); // 默认创建时间为当前时间
        }
        if (wmChannel.getIsDefault() == null) {
            wmChannel.setIsDefault(true); // 默认频道默认
        }
    }

    public ResponseResult<Map<String, Object>> loadArticleBehavior(ArticleInfoDto dto) {

        //0.检查参数
        if (dto == null || dto.getArticleId() == null || dto.getAuthorId() == null) {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

        // { "isfollow": true, "islike": true,"isunlike": false,"iscollection": true }
        boolean isfollow = false, islike = false, isunlike = false, iscollection = false;

        ApUser user = AppThreadLocalUtil.getUser();
        if(user != null){
            //喜欢行为
            String likeBehaviorJson = (String) cacheService.hGet(BehaviorConstants.LIKE_BEHAVIOR + dto.getArticleId().toString(), user.getId().toString());
            if(StringUtils.isNotBlank(likeBehaviorJson)){
                islike = true;
            }
            //不喜欢的行为
            String unLikeBehaviorJson = (String) cacheService.hGet(BehaviorConstants.UN_LIKE_BEHAVIOR + dto.getArticleId().toString(), user.getId().toString());
            if(StringUtils.isNotBlank(unLikeBehaviorJson)){
                isunlike = true;
            }
            //是否收藏
            String collctionJson = (String) cacheService.hGet(BehaviorConstants.COLLECTION_BEHAVIOR+user.getId(),dto.getArticleId().toString());
            if(StringUtils.isNotBlank(collctionJson)){
                iscollection = true;
            }

            //是否关注
            Double score = cacheService.zScore(BehaviorConstants.APUSER_FOLLOW_RELATION + user.getId(), dto.getAuthorId().toString());
            System.out.println(score);
            if(score != null){
                isfollow = true;
            }

        }

        Map<String, Object> resultMap = new HashMap<>();
        resultMap.put("isfollow", isfollow);
        resultMap.put("islike", islike);
        resultMap.put("isunlike", isunlike);
        resultMap.put("iscollection", iscollection);

        return ResponseResult.okResult(resultMap);
    }

}
